package com.auz.datagenerator.connector.heuristiclink;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.logging.Logger;

import javax.swing.JPanel;

import com.auz.datagenerator.heuristics.value.IValueHeuristic;

/**
 * The link between the connector and the set of value heuristics.
 * @author Aurelien Bonnel
 */
public class ValueHeuristicLink {

	Logger logger = Logger.getLogger("ValueHeuristicLink");
	public final String DEFAULT_DELIMITER = "$";
	private Hashtable<String, IValueHeuristic> mapping;
	private String equation;

	/**
	 * Constructor
	 * @param _mapping - the mapping between heuristics and their identifiers
	 */
	public ValueHeuristicLink(Hashtable<String, IValueHeuristic> _mapping) {
		mapping = _mapping;
	}

	/**
	 * Sets the equation to be as specified
	 * @param _equation - the equation
	 */
	public void setEquation(String _equation) {
		equation = _equation;
	}

	/**
	 * Computes the overall value from the equation replacing the identifiers by
	 * the returned values from their associated value heuristics
	 * @return the generated value
	 */
	public Object compute() {
		String temp = equation;
		for(String s : mapping.keySet()) {
			temp = temp.replace(DEFAULT_DELIMITER.concat(s).concat(DEFAULT_DELIMITER), 
					String.valueOf(mapping.get(s).getValue()));
		}
		logger.info("Expression: " + temp);
		if(equationContainsOperation()) {
			// TODO: Need to validate equation before-hand
			int start = 0;
			int point = temp.indexOf("$.$");
			while(point != -1) {
				String tmpEquation = temp.substring(start, point+1);
				Parser tmpParser = new Parser(tmpEquation);
				// If there is an expression to calculate
				if(isArithmetic(tmpEquation)) {
					double tmpExpression = tmpParser.parseExpression();
					temp.replace(tmpEquation, String.valueOf(tmpExpression));
				}
				start = point;
				point = temp.indexOf("$.$", start);
			}
			if(equation.contains("+") || 
					equation.contains("*") || 
					equation.contains("-") ||
					equation.contains("/")) {
				// Equation producing a number
				Parser p = new Parser(temp);
				double expression = p.parseExpression();
				for(String s : mapping.keySet()) {
					mapping.get(s).feeback(expression);
				}
				return expression;
			} else {
				return temp;
			}
		} else {
			return temp;
		}
	}

	private boolean equationContainsOperation() {
		return (isArithmetic(equation) ||
				equation.contains("."));
	}

	private boolean isArithmetic(String _expression) {
		return (_expression.contains("+") || 
				_expression.contains("*") || 
				_expression.contains("-") ||
				_expression.contains("/"));
	}
	
	private boolean isPureArithmetic(String _expression) {
		return isArithmetic(_expression) && ! _expression.contains(".");
	}

	/**
	 * Fetches the GUI component, a JPanel, for the heuristic link. The individual heuristic
	 * panels are automatically added for simplicity.
	 * @return a JPanel ready to be inserted in a GUI
	 */
	public JPanel fetchGUIComponent() {
		List<JPanel> heuristicPanels = new ArrayList<JPanel>();
		Iterator<Entry<String, IValueHeuristic>> iter = mapping.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<String, IValueHeuristic> entry = (Entry<String, IValueHeuristic>) iter.next();
			if(entry.getValue().fetchGUIComponent() != null)
				heuristicPanels.add(entry.getValue().fetchGUIComponent());
		}
		return new ValueHeuristicLinkPanel(heuristicPanels);
	}

}
